package com.lecture.junit.tdd.example;


import java.util.Calendar;
import java.util.concurrent.atomic.AtomicInteger;

public abstract class LoginServiceState {

    AtomicInteger count;

    public void login(LoginServiceInterface context, IAccount acc, String password) {
        if (acc.passwordMatches(password)) {
            if (acc.isLoggedIn()) {
                throw new AccountAlreadyLoggedInException();
            }
            if (acc.isRevoked()) {
                throw  new AccountIsRevokedException();
            }
            if (acc.isExpired()) {
                throw new PasswordExpiredException();
            }
            if (!checkAccount(acc)) {
                acc.setRevoked();
                return;
            }
            acc.setLoggedIn();
            context.setState(acc.getUserName(), new AwaitFirstLoginAttempt());
        } else {
            handlePasswordFail(context, acc);
        }
    }

    private boolean checkAccount(IAccount acc) {
        Calendar date = Calendar.getInstance();
        date.add(Calendar.DAY_OF_YEAR, -45);
        if (date.after(acc.getLastAccessDate())) {
            return false;
        } else {
            return true;
        }
    }

    protected abstract void handlePasswordFail(LoginServiceInterface context, IAccount acc);

    public void changePassword(LoginServiceInterface context, IAccount acc,
            String oldPassword, String newPassword) throws AccountIsNotLoggedInException, OldPasswordException {
        if (acc.passwordMatches(oldPassword)) {
            if (!checkAccount(acc)) {
                acc.setRevoked();
                return;
            }
            acc.changePassword(oldPassword, newPassword);
        } else {
            handlePasswordFail(context, acc);
        }
    }
}
